/*
 * @Author: Ryan Huang
 * @Date: 2019-04-02 21:40:34
 * @Description:
 */
package main

import (
	"bufio"
	"fmt"
	"math/rand"
	"os"
	"sort"
	"time"
)

type gradeStruct struct {
	Name  string
	Grade int
}

type gradeStructs []gradeStruct

func main() {
	grades := generalGrades()
	fmt.Println(grades)
	fmt.Println(grades)
	fmt.Println(grades)
	fmt.Println(grades)
	fmt.Println()
	gradeStructs := map2Struct(grades)
	fmt.Println(gradeStructs)
	sort.Sort(gradeStructs)
	fmt.Println(gradeStructs)
	grades = struct2Map(&gradeStructs)
	fmt.Println()
	fmt.Println(grades)
	fmt.Println(grades)
	fmt.Println(grades)
	fmt.Println(grades)
}

func struct2Map(structs *gradeStructs) map[string]int {
	var grades = map[string]int{}
	for _, gradeStruct := range *structs {
		grades[gradeStruct.Name] = gradeStruct.Grade
	}
	return grades
}

func (this gradeStructs) Len() int {
	return len(this)
}

func (this gradeStructs) Less(i, j int) bool {
	return this[i].Grade < this[j].Grade
}

func (this gradeStructs) Swap(i, j int) {
	this[i], this[j] = this[j], this[i]
}

func map2Struct(grades map[string]int) gradeStructs {
	var gradeStructs gradeStructs
	for name, grade := range grades {
		gradeStruct := gradeStruct{name, grade}
		gradeStructs = append(gradeStructs, gradeStruct)
	}
	return gradeStructs
}

func generalGrades() map[string]int {
	var grades = map[string]int{}
	inputReader := bufio.NewReader(os.Stdin)
	for {
		rand.Seed(time.Now().UnixNano())
		grade := rand.Intn(101)
		line, _, _ := inputReader.ReadLine()
		name := string(line)
		if name == "exit" {
			break
		}
		grades[name] = grade
	}
	return grades
}
